﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using RouteEditor;

namespace Senthil.Mobile.WhereAmI
{
    public partial class RouteEditorForm : Form
    {
        List<Location> allLocations = new List<Location>();
        List<LocationGroup> locationGroups = new List<LocationGroup>();

        string routeFileLocation = "";

        Route loadedRoute;

        string operatorName = "";

        public RouteEditorForm()
        {
            InitializeComponent();
        }

        private TimeSpan GetTimeSpan(ListViewItem item)
        {
            return TimeSpan.Parse(item.SubItems[0].Text);
        }

        private void SetTimeSpan(ListViewItem item, TimeSpan timeSpan)
        {
            item.SubItems[0].Text = timeSpan.ToString();
        }

        private void ignoreSelectedToolStripMenuItem_Click(object sender, EventArgs e) { }
        

        private void combineSameToolStripMenuItem_Click(object sender, EventArgs e){}

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Multiselect = false;
                if (openFileDialog.ShowDialog(this) != DialogResult.OK)
                    return;

                routeFileLocation = openFileDialog.FileName;
                loadedRoute = RouteManager.LoadRoute(openFileDialog.FileName);

                TimeSpan totalRouteTime = loadedRoute.GetTimeTaken(loadedRoute.Start, loadedRoute.Destination);
                routeTimeline1.TimeToShow = totalRouteTime;

                foreach (LocationGroup lg in loadedRoute.LocationGroups)
                {
                    AddLocationGroupToListView(lg);
                }

                locationsGrid.AutoGenerateColumns = true;
                locationsGrid.DataSource = loadedRoute.RoutePoints;
                locationsGrid.Columns["LocationId"].Visible = false;
                locationsGrid.Columns["RelativeIndexInRoute"].Visible = false;
                locationsGrid.Columns["SerializedTimeFromPreviousRoutePoint"].Visible = false;
            }
        }

        private void InsertLocationGroupInListView(int index, LocationGroup lg)
        {
            ListViewItem item = new ListViewItem(lg.Name);
            item.Tag = lg;
            item.Checked = lg.IsSpecial;

            locationGroupsListView.Items.Insert(index, item);
        }

        private void AddLocationGroupToListView(LocationGroup lg)
        {
            ListViewItem item = new ListViewItem(lg.Name);
            item.Tag = lg;
            item.Checked = lg.IsSpecial;

            locationGroupsListView.Items.Add(item);
        }

        private void HighlightLocationGroup(LocationGroup lg)
        {
            TimeSpan start = TimeSpan.Zero;
            TimeSpan end = TimeSpan.Zero;
            loadedRoute.GetTimeOffsets(lg, out start, out end);

            bool noLocationsInLocationGroup = lg.Locations.Length == 0;

            routeTimeline1.Highlight(new HighlightInfo()
            {
                Description = lg.Name + (noLocationsInLocationGroup ? "[NO LOCATIONS ASSOCIATED]" : ""),
                Start = start,
                Duration = end - start,
                StartText = noLocationsInLocationGroup ? "" : lg.Locations[0].Name,
                EndText = noLocationsInLocationGroup ? "" : lg.Locations[lg.Locations.Length - 1].Name
            });

            locationsGrid.ClearSelection();

            DataGridViewRow lastSelectedRow = null;

            foreach (Location location in lg.Locations)
            {
                foreach (DataGridViewRow row in locationsGrid.Rows)
                {
                    if (loadedRoute.RoutePoints[row.Index].Location == location)
                    {
                        lastSelectedRow = row;
                        row.Selected = true;
                    }
                }
            }

            if (lastSelectedRow != null)
                locationsGrid.FirstDisplayedScrollingRowIndex = lastSelectedRow.Index > 5 ? lastSelectedRow.Index - 5 : lastSelectedRow.Index;
        }

        private void assignToSelectedButton_Click(object sender, EventArgs e)
        {
            LocationGroup lg = GetSelectedLocationGroup();

            lg.RemoveAllLocations();

            List<Location> locationsToAdd = new List<Location>();

            foreach (DataGridViewRow row in locationsGrid.SelectedRows)
            {
                Location location = loadedRoute.RoutePoints[row.Index].Location;

                if (location.LocationGroup != null)
                    location.LocationGroup.RemoveLocation(location);

                locationsToAdd.Add(location);
            }

            locationsToAdd.Reverse();

            locationsToAdd.ForEach(location => lg.AddLocation(location));
        }

        private LocationGroup GetSelectedLocationGroup()
        {
            return (LocationGroup)locationGroupsListView.Items[locationGroupsListView.SelectedIndices[0]].Tag;
        }

        private void expandLeftButton_Click(object sender, EventArgs e)
        {
            int index = locationGroupsListView.SelectedIndices[0];

            if (index == 0)
                return;

            LocationGroup lg = (LocationGroup)locationGroupsListView.Items[index].Tag;
            LocationGroup previous = (LocationGroup)locationGroupsListView.Items[index - 1].Tag;

            Location[] previousLocations = previous.Locations;

            if (previousLocations.Length > 0)
            {
                Location lastLocation = previousLocations[previousLocations.Length - 1];
                previous.RemoveLocation(lastLocation);
                lg.InsertFirst(lastLocation);
            }

            HighlightLocationGroup(lg);
        }

        private void expandRightButton_Click(object sender, EventArgs e)
        {
            int index = locationGroupsListView.SelectedIndices[0];
            LocationGroup lg = (LocationGroup)locationGroupsListView.Items[index].Tag;

            if (index == locationGroupsListView.Items.Count - 1)
            {   
                Location lastLocation = null;

                if (lg.Locations.Length == 0)
                {
                    // First LG will always have one location, so if there are no locations, index can't be zero, -1 is safe
                    LocationGroup previousLg = (LocationGroup)locationGroupsListView.Items[index - 1].Tag;
                    lastLocation = previousLg.Locations[previousLg.Locations.Length - 1];
                }
                else
                    lastLocation = lg.Locations[lg.Locations.Length - 1];

                Location location = loadedRoute.GetNextLocation(lastLocation);

                if (location != null)
                    lg.AddLocation(location);
            }
            else
            {
                LocationGroup next = (LocationGroup)locationGroupsListView.Items[index + 1].Tag;

                Location[] nextLocations = next.Locations;

                if (nextLocations.Length > 0)
                {
                    Location firstLocation = nextLocations[0];
                    next.RemoveLocation(firstLocation);
                    lg.AddLocation(firstLocation);
                }
            }

            HighlightLocationGroup(lg);
        }

        private void deleteLocationGroupButton_Click(object sender, EventArgs e)
        {
            LocationGroup lg = GetSelectedLocationGroup();
            loadedRoute.Disassociate(lg);
            locationGroupsListView.Items.RemoveAt(locationGroupsListView.SelectedIndices[0]);
        }

        private void clearAllLocationGroupsButton_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in locationGroupsListView.Items)
            {
                loadedRoute.Disassociate((LocationGroup)item.Tag);
            }

            locationGroupsListView.Items.Clear();
        }

        private void locationGroupsListView_SelectedIndexChanged(object sender, EventArgs e)
        {
            deleteLocationGroupButton.Enabled = expandLeftButton.Enabled =
                expandRightButton.Enabled = (locationGroupsListView.SelectedIndices.Count != 0);

            if (locationGroupsListView.SelectedIndices.Count != 0)
            {
                HighlightLocationGroup(GetSelectedLocationGroup());
            }
        }

        private void addNewLocationGroupButton_Click(object sender, EventArgs e)
        {
            int index = -1;

            if (locationGroupsListView.SelectedIndices.Count > 0)
                index = locationGroupsListView.SelectedIndices[0];

            string groupName = "NewLocationGroup";
            LocationGroup locationGroup = new LocationGroup(groupName);
            locationGroup.Name = groupName;

            var firstLocation = loadedRoute.RoutePoints[0].Location;

            if (locationGroupsListView.Items.Count == 0)
                locationGroup.AddLocation(firstLocation);

            loadedRoute.Associate(locationGroup);
            InsertLocationGroupInListView(index + 1, locationGroup);

            locationGroupsListView.Items[index + 1].Selected = true;
            locationGroupsListView.Items[index + 1].BeginEdit();
        }

        private void locationGroupsListView_AfterLabelEdit(object sender, LabelEditEventArgs e)
        {
            LocationGroup lg = (LocationGroup)locationGroupsListView.Items[e.Item].Tag;
            lg.Name = e.Label;

            HighlightLocationGroup(lg);
        }

        private void shrinkRightButton_Click(object sender, EventArgs e)
        {
            LocationGroup lg = GetSelectedLocationGroup();
            Location[] locations = lg.Locations;

            if (locations.Length > 0)
                lg.RemoveLocation(locations[locations.Length - 1]);

            HighlightLocationGroup(lg);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void saveToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            RouteManager.Save(loadedRoute, routeFileLocation);
        }

        private void locationGroupsListView_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            ((LocationGroup)e.Item.Tag).IsSpecial = e.Item.Checked;
        }
    }
}
